package com.springBoot.commonClass;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.springBoot.exception.BusinessFailureException;

import java.util.Calendar;
import java.util.Date;

public class JwtUtils {

    /**
     * 签发对象：这个用户的id
     * 签发时间：现在
     * 有效时间：30分钟
     * 载荷内容：暂时设计为：这个人的名字，这个人的昵称
     * 加密密钥：这个人的id加上一串字符串
     */
    public static String createToken(String userId, String userAcc, String userName){
        Calendar nowTime = Calendar.getInstance();
        nowTime.add(Calendar.MINUTE, 30);
        Date expiresDate = nowTime.getTime();

        return JWT.create().withAudience(userId) //签发对象
            .withIssuedAt(new Date()) //发行时间
            .withExpiresAt(expiresDate) //有效时间
            .withClaim("userName", userName) //载荷，随便写几个
            .withClaim("userAcc", userAcc)
            .sign(Algorithm.HMAC256(userId + "jian.f.liu"));
    }

    /**
     * 检验合法性，其中secret参数就应该是传入的用户的id
     * @param token
     *
     */
    public static void verifyToken(String token, String secret) throws Exception {
        DecodedJWT jwt = null;
        try{
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(secret + "jian.f.liu")).build();
            jwt = verifier.verify(token);
        }catch (Exception e){
            //校验失败
            //这里可以抛出自定义异常
//            throw new BusinessFailureException(true);
//            throw new Exception("verifyToken出错");
            throw new BusinessFailureException(true, new Exception("token信息失效"));
        }
    }

    /**
     * 获取签发对象
     */
    public static String getAudience(String token) throws Exception {
        String audience = null;
        try {
            audience = JWT.decode(token).getAudience().get(0);
        }catch (JWTDecodeException j){
//            throw new BusinessFailureException(true);
            throw new Exception("getAudience出错");
        }
        return audience;
    }

    /**
     * 通过载荷名字获取载荷的值
     */
    public static Claim getClaimByName(String token, String name){
        return JWT.decode(token).getClaim(name);
    }

}
